package com.ruoyi.huanjing.service.impl;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Stream;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.huanjing.domain.DirItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.huanjing.mapper.DirectoryManagementMapper;
import com.ruoyi.huanjing.domain.DirectoryManagement;
import com.ruoyi.huanjing.service.IDirectoryManagementService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 目录管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-07-28
 */
@Service
public class DirectoryManagementServiceImpl extends ServiceImpl<DirectoryManagementMapper,DirectoryManagement> implements IDirectoryManagementService
{
    @Autowired
    private DirectoryManagementMapper directoryManagementMapper;
    @Autowired
    private RedisCache redisCache;

    /**
     * 查询目录管理
     * 
     * @param id 目录管理主键
     * @return 目录管理
     */
    @Override
    public DirectoryManagement selectDirectoryManagementById(Long id)
    {
        return directoryManagementMapper.selectDirectoryManagementById(id);
    }

    /**
     * 查询目录管理列表
     * 
     * @param directoryManagement 目录管理
     * @return 目录管理
     */
    @Override
    public List<DirectoryManagement> selectDirectoryManagementList(DirectoryManagement directoryManagement)
    {
        return directoryManagementMapper.selectDirectoryManagementList(directoryManagement);
    }

    /**
     * 新增目录管理
     * 
     * @param directoryManagement 目录管理
     * @return 结果
     */
    @Override
    public int insertDirectoryManagement(DirectoryManagement directoryManagement)
    {
        directoryManagement.setCreateTime(DateUtils.getNowDate());
        return directoryManagementMapper.insertDirectoryManagement(directoryManagement);
    }

    /**
     * 修改目录管理
     * 
     * @param directoryManagement 目录管理
     * @return 结果
     */
    @Override
    public int updateDirectoryManagement(DirectoryManagement directoryManagement)
    {
        directoryManagement.setUpdateTime(DateUtils.getNowDate());
        return directoryManagementMapper.updateDirectoryManagement(directoryManagement);
    }

    /**
     * 批量删除目录管理
     * 
     * @param ids 需要删除的目录管理主键
     * @return 结果
     */
    @Override
    public int deleteDirectoryManagementByIds(Long[] ids)
    {
        return directoryManagementMapper.deleteDirectoryManagementByIds(ids);
    }

    /**
     * 删除目录管理信息
     * 
     * @param id 目录管理主键
     * @return 结果
     */
    @Override
    public int deleteDirectoryManagementById(Long id)
    {
        return directoryManagementMapper.deleteDirectoryManagementById(id);
    }

    /**
     * 目录结构入库
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSql() {
        //构造目录结构集合
        insertAll();
        return 111;
    }

    private static final List<String> yJList=new ArrayList<>(Arrays.asList("大气环境", "海面环境", "陆地环境", "水中环境"));
    private static List<String> tilsList=new ArrayList<>(Arrays.asList("台湾", "香港"));

    @Override
    public List<Map<String, Object>> directoryTree() {
        String disk = redisCache.getCacheObject("disk").toString();
        //这里是判断是否有总路径，决定是否直接置灰，不走判断，即直接不去循环扫描文件夹
        boolean isGray = Boolean.parseBoolean(redisCache.getCacheObject("isGray").toString());
        //需要扫描的路径
        String basePath = disk+"环境数据";
        // 查询所有目录
        List<DirectoryManagement> allDirs = directoryManagementMapper.selectList(null);

        // id -> 节点 Map
        Map<Long, Map<String, Object>> idNodeMap = new HashMap<>();
        for (DirectoryManagement dm : allDirs) {
            Map<String, Object> node = new HashMap<>();
            node.put("id", convertLongToString(dm.getId()));
            node.put("name", dm.getDirectoryName());
            node.put("path", basePath+dm.getPath());
            node.put("disabled", isGray?isGray:dm.getDisabled());
            node.put("isLeaf", dm.getIsLeaf());
            node.put("parentId", dm.getParentId());
            node.put("children", new ArrayList<Map<String, Object>>()); // 初始化子节点列表
            // 判断是否禁用（只针对叶子节点）
            if (Boolean.TRUE.equals(dm.getIsLeaf())) {
                String fullPath = basePath + dm.getPath().replace("\\", File.separator);
                //高程做处理
                if ("数字高程".equals(dm.getDirectoryName())){
                    node.put("isGaoCheng", true);
//                    node.put("disabled",false);
                    node.put("disabled", isGray?isGray:(!hasFilesInDir(fullPath+File.separator+"中朝边境"))); // 没文件就禁用
                } else if ("地物类型".contains(dm.getDirectoryName())) {
                    node.put("disabled", isGray?isGray:(!hasFilesInDir(fullPath+File.separator+"ESA_WorldCover_10m_2020_v100_Map"))); // 没文件就禁用
                }else if (tilsList.contains(dm.getDirectoryName())) {
                    if ("台湾".equals(dm.getDirectoryName())) {
                        node.put("disabled", isGray?isGray:((!hasFilesInDir(fullPath+File.separator+"TAOYUAN-3DTiles")) )); // 没文件就禁用
                    }else {
                        node.put("disabled", isGray?isGray:((!hasFilesInDir(fullPath+File.separator+"11-SE-6B")) )); // 没文件就禁用
                    }

                } else {
                    node.put("disabled", isGray?isGray:(!hasFilesInDir(fullPath))); // 没文件就禁用
                }
            }

            idNodeMap.put(dm.getId(), node);
        }

        // 构造树结构
        List<Map<String, Object>> rootList = new ArrayList<>();
        for (DirectoryManagement dm : allDirs) {
            Long parentId = dm.getParentId();
            Map<String, Object> currentNode = idNodeMap.get(dm.getId());

            if (parentId == null || parentId == 0) {
                rootList.add(currentNode); // 根节点
            } else {
                Map<String, Object> parentNode = idNodeMap.get(parentId);
                if (parentNode != null) {
                    List<Map<String, Object>> children = (List<Map<String, Object>>) parentNode.get("children");
                    children.add(currentNode);
                }
            }
        }

        return rootList;
    }

    private Object convertLongToString(Object value) {
        if (value instanceof Long) {
            return value.toString();
        }
        return value;
    }

    /**
     * 获取叹号信息
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> getDirectoryInfo(Long id) {
        DirectoryManagement directoryManagement = directoryManagementMapper.selectById(id);
        Map<String,Object> resultMap = new HashMap<>();
        if (ObjectUtils.isNotEmpty(directoryManagement)) {
            Boolean measured = directoryManagement.getMeasured();
            String isMe="";
            if (ObjectUtils.isNotEmpty(measured) && measured) {
                isMe = "(实测)";
            }
            resultMap.put("name", directoryManagement.getDirectoryName()+isMe);
            List<String> list = Arrays.asList(
                "条目数", "内存大小",
                "文件格式", "数据来源", "空间范围", "时间范围", 
                "空间分辨率", "时间分辨率"
            );
            List<Map<String, Object>> dataList = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                Map<String,Object> map = new HashMap<>();
                map.put("name", list.get(i));
                if (i==0){
                    map.put("value", ObjectUtils.isNotEmpty(directoryManagement.getDirectoryName())?directoryManagement.getNumber():"13547"
                );
                }else if (i==1){
                    map.put("value", ObjectUtils.isNotEmpty(directoryManagement)?directoryManagement.getMemorySize():"0.5TB"
                );
//                }else if (i==2){
//                    map.put("value", ObjectUtils.isNotEmpty(directoryManagement)?directoryManagement.getTotalDada():"45315"
//                );
                }else if (i==2){
                    map.put("value", ObjectUtils.isNotEmpty(directoryManagement)?directoryManagement.getFileType():"hdf"
                );
                }else if (i==3){
                    map.put("value", ObjectUtils.isNotEmpty(directoryManagement)?directoryManagement.getDataSource():"MOD11C1"
                );
                }else if (i==4){
                    map.put("value", ObjectUtils.isNotEmpty(directoryManagement)?directoryManagement.getSpacialScale():"全球"
                );
                }else if (i==5){
                    map.put("value", ObjectUtils.isNotEmpty(directoryManagement)?directoryManagement.getTimeScale():"2003-2020"
                );
                }else if (i==6){
                    map.put("value", ObjectUtils.isNotEmpty(directoryManagement)?directoryManagement.getSpaceResolution():"0.05"
                );
                }else if (i==7){
                    map.put("value", ObjectUtils.isNotEmpty(directoryManagement)?directoryManagement.getTimeResolution():"日"
                );
                }
                dataList.add(map);
            }
            resultMap.put("paramsList", dataList);
        }
        return resultMap;
    }

    /**
     * 判断某个目录是否存在文件
     *
     * @param fullPath 完整的物理路径（例如 E:/环境数据/大气环境/基本特性/能见度）
     * @return true 表示该目录下存在文件
     */
    public static boolean hasFilesInDir(String fullPath) {
        File dir = new File(fullPath);
        if (!dir.exists() || !dir.isDirectory()) {
            return false;
        }

        // 优化扫描速度，尝试找到第一个文件，找到就立即返回true
        try (Stream<Path> stream = Files.list(Paths.get(fullPath))) {
            return stream.anyMatch(Files::isRegularFile);
        } catch (IOException e) {
            // 处理异常，如权限问题等
            return false;
        }
    }

    /**
     * 构造目录数据,调用初始插入
     */
    public void insertAll() {
        // 构建根目录结构
        List<DirItem> rootDirs = Arrays.asList(
                // 1. 大气环境目录
                new DirItem("大气环境", Arrays.asList(
                        new DirItem("基本特性", Arrays.asList(
                                new DirItem("能见度", Arrays.asList(
                                        // 叶子节点 - 水平能见度
                                        new DirItem("水平能见度", null,
                                                null, null, true,  
                                                null, null, null,  
                                                null, null, null, null  
                                        )
                                )),
                                new DirItem("大气廓线", Arrays.asList(
                                        new DirItem("大气温度廓线", null,
                                                194761, "19.5TB", null,  
                                                194761, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("大气湿度廓线", null,
                                                183960, "18.4TB", null,  
                                                183960, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("大气压力廓线", null,
                                                214958, "20.2TB", null,  
                                                214958, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("大气成分廓线", Arrays.asList(
                                                new DirItem("一氧化碳", null,
                                                        26560, "0.5TB", true,  
                                                        26560, null, null,  
                                                        null, null, null, null  
                                                ),
                                                new DirItem("二氧化碳", null,
                                                        26560, "0.5TB", true,  
                                                        26560, null, null,  
                                                        null, null, null, null  
                                                ),
                                                new DirItem("臭氧", null,
                                                        26561, "0.6TB", true,  
                                                        26561, null, null,  
                                                        null, null, null, null  
                                                )
                                        )),
                                        new DirItem("折射率廓线", null,
                                                61597, "1.2TB", true,  
                                                61597, null, null,  
                                                null, null, null, null  
                                        )
                                )),
                                new DirItem("云", Arrays.asList(
                                        new DirItem("云参数", null,
                                                99645, "2TB", null,  
                                                99645, null, null,  
                                                null, null, null, null  
                                        )
                                )),
                                new DirItem("雨", Arrays.asList(
                                        new DirItem("雨参数", null,
                                                84315, "1.7TB", null,  
                                                84315, null, null,  
                                                null, null, null, null  
                                        )
                                ))
                        )),
                        new DirItem("光学特性", Arrays.asList(
                                new DirItem("大气辐射传输特性", Arrays.asList(
                                        new DirItem("大气辐射亮度", null,
                                                null, null, null,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("大气透过率", null,
                                                23410, "0.8TB", true,  
                                                23410, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("消光系数", null,
                                                15330, "0.5TB", true,  
                                                15330, null, null,  
                                                null, null, null, null  
                                        )
                                )),
                                new DirItem("太阳", Arrays.asList(
                                        new DirItem("太阳总辐射照度", null,
                                                107310, "2.1TB", null,  
                                                107310, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("太阳直接辐射照度", null,
                                                81469, "1.7TB", null,  
                                                81469, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("太阳散射辐射照度", null,
                                                25841, "0.4TB", null,  
                                                25841, null, null,  
                                                null, null, null, null  
                                        )
                                ))
                        ))
                )),

                // 2. 陆地环境目录
                new DirItem("陆地环境", Arrays.asList(
                        new DirItem("基本特性", Arrays.asList(
                                new DirItem("地形地貌", Arrays.asList(
                                        new DirItem("地物类型", null,
                                                null, null, null,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("地面温度", null,
                                                22995, "1.4TB", null,  
                                                22995, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("数字高程", null,
                                                null, "3TB", null,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("地面粗糙度", null,
                                                15530, "0.9TB", null,  
                                                15530, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("植被参数", null,
                                                7665, "0.5TB", null,  
                                                7665, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("地面倾斜摄影", Arrays.asList(
                                                new DirItem("香港", null,
                                                        null, "15GB", null,  
                                                        null, null, null,  
                                                        null, null, null, null  
                                                ),
                                                new DirItem("台湾", null,
                                                        null, "16GB", null,  
                                                        null, null, null,  
                                                        null, null, null, null  
                                                )
                                        ))
                                )),
                                new DirItem("物性参数", Arrays.asList(
                                        new DirItem("热参数", null,
                                                30660, "1.8TB", null,  
                                                30660, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("光学参数", null,
                                                null, "24TB", null,  
                                                null, null, null,  
                                                null, null, null, null  
                                        )
                                ))
                        )),
                        new DirItem("光学特性", Arrays.asList(
                                new DirItem("辐射特性", Arrays.asList(
                                        new DirItem("辐射亮度", null,
                                                null, null, null,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("光学图像", null,
                                                null, null, null,  
                                                null, null, null,  
                                                null, null, null, null  
                                        )
                                ))
                        ))
                )),

                // 3. 海面环境目录
                new DirItem("海面环境", Arrays.asList(
                        new DirItem("基本特性", Arrays.asList(
                                new DirItem("海面参数", Arrays.asList(
                                        new DirItem("海表温度", null,
                                                7665, "0.08TB", true,  
                                                7665, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("波高", null,
                                                3528, "0.03TB", true,  
                                                3528, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("波向", null,
                                                12045, "0.11TB", true,  
                                                12045, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("波周期", null,
                                                7891, "0.07TB", true,  
                                                7891, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("海谱", null,
                                                19432, "0.18TB", true,  
                                                19432, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("流速", null,
                                                15684, "0.15TB", true,  
                                                15684, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("流向", null,
                                                4368, "0.04TB", true,  
                                                4368, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("海况", null,
                                                9835, "0.09TB", true,  
                                                9835, null, null,  
                                                null, null, null, null  
                                        )
                                ))
                        )),
                        new DirItem("光学特性", Arrays.asList(
                                new DirItem("辐射参数", Arrays.asList(
                                        new DirItem("反射率", null,
                                                null, "1.4TB", null,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("光谱反射率", null,
                                                null, "0.9TB", null,  
                                                null, null, null,  
                                                null, null, null, null  
                                        )
                                ))
                        )),
                        new DirItem("电磁特性", Arrays.asList(
                                new DirItem("幅度特性", Arrays.asList(
                                        new DirItem("时变散射系数", null,
                                                null, null, true,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("平均散射系数", null,
                                                null, null, true,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("幅度概率密度函数", null,
                                                null, null, true,  
                                                null, null, null,  
                                                null, null, null, null  
                                        )
                                )),
                                new DirItem("相关特性", Arrays.asList(
                                        new DirItem("时间相关特性", null,
                                                null, null, true,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("距离相关特性", null,
                                                null, null, true,  
                                                null, null, null,  
                                                null, null, null, null  
                                        )
                                )),
                                new DirItem("多普勒特性", Arrays.asList(
                                        new DirItem("多普勒谱密度", null,
                                                null, null, true,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("时变－多普勒谱密度", null,
                                                null, null, true,  
                                                null, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("一维图像", null,
                                                null, null, true,  
                                                null, null, null,  
                                                null, null, null, null  
                                        )
                                ))
                        ))
                )),

                // 4. 水中环境目录
                new DirItem("水中环境", Arrays.asList(
                        new DirItem("基本特性", Arrays.asList(
                                new DirItem("水体参数", Arrays.asList(
                                        new DirItem("海水温度剖面", null,
                                                3669, "21.6GB", null,  
                                                3669, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("海水密度", null,
                                                5406, "32.4GB", null,  
                                                5406, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("海水盐度", null,
                                                4125, "25.5GB", null,  
                                                4125, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("水深", null,
                                                2988, "17.4GB", null,  
                                                2988, null, null,  
                                                null, null, null, null  
                                        ),
                                        new DirItem("海水流速流向", null,
                                                2684, "16.1GB", null,  
                                                2684, null, null,  
                                                null, null, null, null  
                                        )
                                ))
                        ))
                ))
        );



        //调用开始插入
        insertDirectories(0L, "\\", rootDirs);
    }



    /**
     * 递归插入目录
     * @param parentId 父目录ID，顶级传 0
     * @param parentPath 父目录路径，顶级传 "\"
     * @param dirs 当前层目录列表
     */
    public void insertDirectories(Long parentId, String parentPath, List<DirItem> dirs) {
        if (dirs == null || dirs.isEmpty()) {
            return;
        }

        long orderNum = 1L;
        for (DirItem item : dirs) {
            DirectoryManagement dm = new DirectoryManagement();
            dm.setDirectoryName(item.getName());
            dm.setParentId(parentId);
            dm.setOrderNum(orderNum++);
            dm.setDisabled(false);
            dm.setStatus("0");
            dm.setNumber(item.getNumber());       // 设置条目数
            dm.setMemorySize(item.getMemorySize()); // 设置内存大小
            dm.setMeasured(item.getMeasured());   // 设置是否实测

            // 拼接路径
            String path = parentPath.endsWith("\\") ? parentPath + item.getName() : parentPath + "\\" + item.getName();
            dm.setPath(path);

            // 先假设叶子节点
            boolean isLeaf = (item.getChildren() == null || item.getChildren().isEmpty());
            dm.setIsLeaf(isLeaf);


            // 插入数据库
            directoryManagementMapper.insert(dm);

            Long newId = dm.getId();

            // 如果有子节点，先更新当前节点 isLeaf = false
            if (!isLeaf) {
                dm.setIsLeaf(false);
                directoryManagementMapper.updateById(dm);
                // 递归插入子节点
                insertDirectories(newId, path, item.getChildren());
            }
        }
    }
}
